package com.sinping.qh.repository.mongo.records.impl;

import com.google.common.collect.Lists;
import com.sinping.qh.api.exception.HandlerException;
import com.sinping.qh.api.support.ConstEum;
import com.sinping.qh.api.support.FrontPage;
import com.sinping.qh.repository.mongo.records.CheckRecordsRepository;
import com.sinping.qh.service.MongoManager;
import com.sinping.qh.utils.time.DateFormatUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * @author zhangjin
 * @create 2018/6/27
 */
@Service
public class CheckRecordsRepositoryImpl {


    @Autowired
    CheckRecordsRepository checkRecordsRepository;

    @Autowired
    private MongoTemplate template;

    @Autowired
    private MongoManager mongoManager;



    public <T> List<T> findPageByUniting(List<String> unitIDList,
                                         List<String> labIDList,
                                         List<String> groupParams,
                                         Pageable page,
                                 Class<?> clazz, Class<T> targetClazz) {
        List<AggregationOperation> operations = Lists.newArrayList();


        //添加权限
        Criteria mainCriteria =new Criteria();
        Criteria one =Criteria.where("check_unit_id").in(unitIDList);
        Criteria two =Criteria.where("check_lab_id").in(labIDList);
        mainCriteria.orOperator(one,two);
        operations.add(Aggregation.match(mainCriteria));
        if (page!=null){
            SortOperation sortOperation = new SortOperation(page.getSort());
            operations.add(sortOperation);
        }

        //查询检查状态已审核的
        Criteria checkStatusOption =Criteria.where("check_status").is("3");
        operations.add(Aggregation.match(checkStatusOption));

        //查询隐患记录数据不为0和隐患状态未完成的检查记录
        LookupOperation lookupOperation
                =LookupOperation.newLookup()
                .from("tb_hidden_danger")
                .localField("_id")
                .foreignField("check_id")
                .as("hidenrecords");
        operations.add(lookupOperation);

        HashSet<String> hiddStatus=new HashSet<>();
        hiddStatus.add("0");
        hiddStatus.add("1");
        hiddStatus.add("2");
        Criteria criteria=Criteria.where("hidenrecords").ne(new HashSet<>())
                .and("hidenrecords.hidden_danger_status").in(hiddStatus);
        operations.add(Aggregation.match(criteria));



        // 统计参数
        GroupOperation group = Aggregation.group(groupParams.toArray(new String[groupParams.size()]));
        group=group.count().as("checkCount");
        operations.add(group);

        if (page!=null){
            SkipOperation skipOperation = new SkipOperation(page.getOffset());
            operations.add(skipOperation);
            LimitOperation limitOperation = new LimitOperation(page.getPageSize());
            operations.add(limitOperation);
        }

        Aggregation aggregation = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, targetClazz);
        return results.getMappedResults();
    }

    public <T> List<T> findPageByUnitingDetail(List<String> unitIDList,
                                               List<String> labIDList,
                                               String checkUnidId,String checkBuildingId,
                                               Pageable page,
                                               Class<T> clazz)
    {
        List<AggregationOperation> operations = Lists.newArrayList();
        //添加权限
        Criteria mainCriteria =new Criteria();
        Criteria one =Criteria.where("check_unit_id").in(unitIDList);
        Criteria two =Criteria.where("check_lab_id").in(labIDList);
        mainCriteria.orOperator(one,two);

        //查询传入的检查院系和楼宇
        mainCriteria.and("check_unit_id").is(checkUnidId).and("check_building_id").is(checkBuildingId);

        if (page!=null){
            SortOperation sortOperation = new SortOperation(page.getSort());
            operations.add(sortOperation);
        }

        //查询检查状态已审核的
        Criteria checkStatusOption =Criteria.where("check_status").is("3");
        operations.add(Aggregation.match(checkStatusOption));

        operations.add(Aggregation.match(mainCriteria));

        //查询隐患记录数据不为0和隐患状态未完成的检查记录
        LookupOperation lookupOperation
                =LookupOperation.newLookup()
                .from("tb_hidden_danger")
                .localField("_id")
                .foreignField("check_id")
                .as("hidenrecords");
        operations.add(lookupOperation);

        HashSet<String> hiddStatus=new HashSet<>();
        hiddStatus.add("0");
        hiddStatus.add("1");
        hiddStatus.add("2");
        Criteria criteria=Criteria.where("hidenrecords").ne(new HashSet<>())
                .and("hidenrecords.hidden_danger_status").in(hiddStatus);
        operations.add(Aggregation.match(criteria));


        if (page!=null){
            SkipOperation skipOperation = new SkipOperation(page.getOffset());
            operations.add(skipOperation);
            LimitOperation limitOperation = new LimitOperation(page.getPageSize());
            operations.add(limitOperation);
        }

        Aggregation aggregation = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, clazz);

        return results.getMappedResults();
    }

    /**
     * 查询整改中和已完成的状态
     * @param unitIDList
     * @param labIDList
     * @param checkStatus
     * @param page 提供分布的支持
     * @param clazz
     * @param <T>
     * @return
     */
    public <T> List<T> findPageByRectifyAndReview(List<String> unitIDList,
                                               List<String> labIDList,
                                               String checkStatus,
                                                  FrontPage frontPage,
                                                  Pageable page,
                                                  Class<T> clazz)
    {

        List<AggregationOperation> operations = Lists.newArrayList();
        //添加权限
        Criteria mainCriteria =new Criteria();
        Criteria one =Criteria.where("check_unit_id").in(unitIDList);
        Criteria two =Criteria.where("check_lab_id").in(labIDList);
        mainCriteria.orOperator(one,two);


        operations.add(Aggregation.match(mainCriteria));

        if (page!=null){
            SortOperation sortOperation = new SortOperation(page.getSort());
            operations.add(sortOperation);
        }

        //查询检查状态已审核的
        Criteria checkStatusOption =Criteria.where("check_status").is("3");
        operations.add(Aggregation.match(checkStatusOption));

        if(StringUtils.isNotBlank(frontPage.getUnitName())) {
            Criteria unitCriteria = Criteria.where("check_unit")
                    .regex("^(.*" + frontPage.getUnitName() + ".*)$");

            operations.add(Aggregation.match(unitCriteria));
        }
//        String startDate=frontPage.getCondition().get("start_time").toString();
//        String endDate=frontPage.getCondition().get("end_time").toString();
        if(frontPage.getStartDate()!=null&&frontPage.getEndDate()!=null) {
             try{
//                Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_ISO_ON_DATE,
//                        startDate);
//                 Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_ISO_ON_DATE,
//                         endDate);
                 String startDate = DateFormatUtil.formatDate("yyyy-MM-dd 00:00:00",
                         frontPage.getStartDate());
                 String endDate = DateFormatUtil.formatDate("yyyy-MM-dd 23:59:59",
                         frontPage.getEndDate());

                 Date newStartDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                         startDate);
                 Date newEndDate = DateFormatUtil.pareDate(DateFormatUtil.PATTERN_DEFAULT_ON_SECOND,
                         endDate);
                Criteria timeCriteria = Criteria.where("check_date")
                        .lte(newEndDate).gte(newStartDate);

                operations.add(Aggregation.match(timeCriteria));
            }catch (Exception e){
                throw new HandlerException(ConstEum.FAIL,"不正确的时间格式");
            }
        }

        //查询隐患记录数据不为0和隐患状态未完成的检查记录
        LookupOperation lookupOperation
                =LookupOperation.newLookup()
                .from("tb_hidden_danger")
                .localField("_id")
                .foreignField("check_id")
                .as("hidenrecords");
        operations.add(lookupOperation);

        if(checkStatus.equals("[012]")) {
            HashSet<String> hiddStatus = new HashSet<>();
            hiddStatus.add("0");
            hiddStatus.add("1");
            hiddStatus.add("2");
            Criteria criteria = Criteria.where("hidenrecords").ne(new HashSet<>())
                    .and("hidenrecords.hidden_danger_status").in(hiddStatus);
            operations.add(Aggregation.match(criteria));
        }
        else if(checkStatus.equals("[3]"))
        {
            HashSet<String> hiddStatus = new HashSet<>();
            hiddStatus.add("0");
            hiddStatus.add("1");
            hiddStatus.add("2");
            Criteria hiddenCriteria =new Criteria();
            Criteria criteriaEmpty = Criteria.where("hidenrecords").is(new HashSet<>());
            Criteria criteriaStatus =Criteria.where("hidenrecords.hidden_danger_status")
                    .nin(hiddStatus);
            hiddenCriteria.orOperator(criteriaEmpty,criteriaStatus);
            operations.add(Aggregation.match(hiddenCriteria));
        }
        if (page!=null){
            SkipOperation skipOperation = new SkipOperation(page.getOffset());
            operations.add(skipOperation);
            LimitOperation limitOperation = new LimitOperation(page.getPageSize());
            operations.add(limitOperation);
        }

        Aggregation aggregation = Aggregation.newAggregation(operations);
        String table = template.getCollectionName(clazz);
        AggregationResults<T> results = template.aggregate(aggregation, table, clazz);

        return results.getMappedResults();
    }
}
